package com.crape.account.bo.impl;

import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;

import com.crape.account.bo.IAccountBO;
import com.crape.account.bo.IAuthEmailBO;
import com.crape.account.dao.IAccountDAO;
import com.crape.account.dao.IAccountRefDAO;
import com.crape.account.dao.IAcctVisitorDAO;
import com.crape.common.bean.LoginUser;
import com.crape.common.constants.ConstantCode;
import com.crape.common.enums.AttentionType;
import com.crape.common.exceptions.BOException;
import com.crape.common.model.Account;
import com.crape.common.model.AccountInfo;
import com.crape.common.thread.ThreadObjManager;
import com.crape.common.tools.DESEncoder;
import com.crape.common.tools.IDESEncoder;

public class AccountBOImpl implements IAccountBO {

	private IAccountDAO accountDAOImpl;
	private IAuthEmailBO authEmailBOImpl;
	private IAccountRefDAO accountRefDAOImpl;
	private IAcctVisitorDAO acctVisitorDAOImpl;

	@Autowired
	public void setAccountDAOImpl(IAccountDAO accountDAOImpl) {
		this.accountDAOImpl = accountDAOImpl;
	}

	@Autowired
	public void setAuthEmailBOImpl(IAuthEmailBO authEmailBOImpl) {
		this.authEmailBOImpl = authEmailBOImpl;
	}

	@Autowired
	public void setAccountRefDAOImpl(IAccountRefDAO accountRefDAOImpl) {
		this.accountRefDAOImpl = accountRefDAOImpl;
	}

	@Autowired
	public void setAcctVisitorDAOImpl(IAcctVisitorDAO acctVisitorDAOImpl) {
		this.acctVisitorDAOImpl = acctVisitorDAOImpl;
	}

	@Override
	public List<AccountInfo> searchAccounts(String searchValue, Integer startIndex, Integer pageSize) throws BOException {
		if (startIndex == null || pageSize == null) {
			return null;
		}
		if (searchValue == null || searchValue.isEmpty()) {
			searchValue = null;
		}
		return accountDAOImpl.searchAccounts(searchValue, startIndex, pageSize);
	}

	@Override
	public Long countSearchAccounts(String searchValue) throws BOException {
		if (searchValue == null || searchValue.isEmpty()) {
			searchValue = null;
		}
		return accountDAOImpl.countSearchAccounts(searchValue);
	}

	@Override
	public void addAccount(Account account) throws BOException {
		if (account == null) {
			return;
		}
		IDESEncoder encoder = DESEncoder.getInstance();
		String password = account.getPassword();
		account.setPassword(encoder.Encode(password));
		account.setNickname(account.getUsername());
		account.setLoginid(account.getUsername());
		account.setSys(ConstantCode.SysName);
		account.setUuid(UUID.randomUUID().toString());
		accountDAOImpl.insertAccount(account);
		authEmailBOImpl.validateAccount(account);
	}

	@Override
	public Account validateOnceMore(String username) throws BOException {
		if (username == null) {
			return null;
		}
		Account account = this.getAccountByUsername(username.trim());
		if (account == null) {
			return null;
		}
		String uuid = UUID.randomUUID().toString();
		account.setUuid(uuid);
		accountDAOImpl.updateAccountUuid(account.getId(), uuid);
		authEmailBOImpl.validateAccount(account);
		return account;
	}

	@Override
	public void updateAccountStatus(Long accountid, Integer status) throws BOException {
		if (accountid == null || status == null) {
			return;
		}
		accountDAOImpl.updateAccountStatus(accountid, status);
	}

	@Override
	public void deleteAccountById(Long id) throws BOException {
		if (id == null) {
			return;
		}
		accountDAOImpl.deleteAccountById(id);
	}

	@Override
	public List<Account> listAccounts(Account account) throws BOException {
		if (account == null) {
			return null;
		}
		return accountDAOImpl.listAccounts(account);
	}

	@Override
	public List<Account> findAccounts(Account account) throws BOException {
		if (account == null) {
			return null;
		}
		if(account.getUsername()!=null){
			account.setUsername(account.getUsername().trim());
		}
		return accountDAOImpl.findAccounts(account);
	}

	@Override
	public Account getAccountById(Long id) throws BOException {
		Account params = new Account();
		params.setId(id);
		List<Account> accounts = accountDAOImpl.listAccounts(params);
		if (accounts == null || accounts.isEmpty()) {
			return null;
		}
		return accounts.get(0);
	}

	@Override
	public Account getAccountByEmail(String email) throws BOException {
		Account params = new Account();
		params.setEmail(email);
		List<Account> accounts = accountDAOImpl.listAccounts(params);
		if (accounts == null || accounts.isEmpty()) {
			return null;
		}
		return accounts.get(0);
	}

	@Override
	public Account getAccountByUsername(String username) throws BOException {
		Account params = new Account();
		params.setUsername(username);
		List<Account> accounts = accountDAOImpl.listAccounts(params);
		if (accounts == null || accounts.isEmpty()) {
			return null;
		}
		return accounts.get(0);
	}

	@Override
	public Long countAllDarrens() throws BOException {
		return accountDAOImpl.countAllDarrens();
	}

	@Override
	public List<AccountInfo> getAllDarrens(Integer startIndex, Integer pageSize) throws BOException {
		if (startIndex == null || pageSize == null || pageSize == 0) {
			return null;
		}
		List<AccountInfo> list = accountDAOImpl.getAllDarrens(startIndex, pageSize);
		if (list == null || list.isEmpty()) {
			return null;
		}
		return list;
	}

	@Override
	public List<AccountInfo> getAllDarrens(Long accountid, Integer startIndex, Integer pageSize) throws BOException {
		if (startIndex == null || pageSize == null || pageSize == 0) {
			return null;
		}
		List<AccountInfo> list = accountDAOImpl.getAllDarrens(startIndex, pageSize);
		if (list == null || list.isEmpty()) {
			return null;
		}
		if (accountid != null) {
			for (AccountInfo accountInfo : list) {
				Long num = accountRefDAOImpl.countAcctRefs(accountid, accountInfo.getAccountid());
				if (num != null && num > 0) {
					accountInfo.setIsattention(AttentionType.yes.getCode());
				} else {
					accountInfo.setIsattention(AttentionType.no.getCode());
				}
			}
		}
		return list;
	}

	@Override
	public Long countDarrens(Long accountid, String email) throws BOException {
		return accountDAOImpl.countDarrens(accountid, email);
	}

	@Override
	public List<AccountInfo> getDarrens(Long accountid, String email, Integer startIndex, Integer pageSize) throws BOException {
		return accountDAOImpl.getDarrens(accountid, email, startIndex, pageSize);
	}

	@Override
	public void addDarrenAttention(Long fansid, Long accountid) throws BOException {
		if (fansid == null || accountid == null) {
			return;
		}
		accountRefDAOImpl.insertAcctRef(fansid, accountid);
		accountDAOImpl.updateAccountAttentionCount(fansid);
		accountDAOImpl.updateAccountFansCount(accountid);
	}

	@Override
	public void cancelDarrenAttention(Long fansid, Long accountid) throws BOException {
		if (fansid == null || accountid == null) {
			return;
		}
		accountRefDAOImpl.backupAcctRef(fansid, accountid);
		accountRefDAOImpl.deleteAcctRef(fansid, accountid);
		accountDAOImpl.updateAccountAttentionCount(fansid);
		accountDAOImpl.updateAccountFansCount(accountid);
	}

	@Override
	public List<AccountInfo> getAccountInfos(AccountInfo accountInfo) throws BOException {
		if (accountInfo == null) {
			return null;
		}
		return accountDAOImpl.getAccountInfos(accountInfo);
	}

	@Override
	public AccountInfo getAccountInfoById(Long accountid) throws BOException {
		AccountInfo params = new AccountInfo();
		params.setAccountid(accountid);
		List<AccountInfo> list = accountDAOImpl.getAccountInfos(params);
		if (list == null || list.isEmpty()) {
			return null;
		}
		AccountInfo accountInfo = list.get(0);
		return accountInfo;
	}

	@Override
	public AccountInfo getAccountInfoByEmail(String email) throws BOException {
		AccountInfo params = new AccountInfo();
		params.setEmail(email);
		List<AccountInfo> list = accountDAOImpl.getAccountInfos(params);
		if (list == null || list.isEmpty()) {
			return null;
		}
		return list.get(0);
	}

	@Override
	public AccountInfo getAccountInfoByUsername(String nickname) throws BOException {
		AccountInfo params = new AccountInfo();
		params.setNickname(nickname);
		List<AccountInfo> list = accountDAOImpl.getAccountInfos(params);
		if (list == null || list.isEmpty()) {
			return null;
		}
		return list.get(0);
	}

	@Override
	public void updateInfo(AccountInfo accountInfo) throws BOException {
		if (accountInfo == null) {
			return;
		}
		Boolean isExist = accountDAOImpl.isAccountInfoExist(accountInfo.getAccountid());
		accountDAOImpl.updateNickname(accountInfo.getAccountid(), accountInfo.getNickname());
		if (isExist) {
			accountDAOImpl.updateAccountInfo(accountInfo);
		} else {
			accountDAOImpl.insertAccountInfo(accountInfo);
		}
	}

	@Override
	public void updatePassword(Long accountid, String password) throws BOException {
		if (accountid == null || password == null) {
			return;
		}
		accountDAOImpl.updatePassword(accountid, password);
	}

	@Override
	public Long statAccountAttention(Long accountid) throws BOException {
		if (accountid == null) {
			throw new IllegalArgumentException("accountid is null");
		}
		return accountDAOImpl.updateAccountAttentionCount(accountid);
	}

	@Override
	public Long statAccountArticle(Long accountid) throws BOException {
		if (accountid == null) {
			throw new IllegalArgumentException("accountid is null");
		}
		return accountDAOImpl.updateAccountArticleCount(accountid);
	}

	@Override
	public Long statAccountQuestion(Long accountid) throws BOException {
		if (accountid == null) {
			throw new IllegalArgumentException("accountid is null");
		}
		return accountDAOImpl.updateAccountQuestionCount(accountid);
	}

	@Override
	public Long countAllAttentions(Long accountid) throws BOException {
		if (accountid == null) {
			return 0L;
		}
		return accountDAOImpl.countAllUserAttentions(accountid);
	}

	@Override
	public Long countAllArticles(Long accountid) throws BOException {
		if (accountid == null) {
			return 0L;
		}
		return accountDAOImpl.countAllUserArticles(accountid);
	}

	@Override
	public Long countAllQuestions(Long accountid) throws BOException {
		if (accountid == null) {
			return 0L;
		}
		return accountDAOImpl.countAllUserQuestions(accountid);
	}

	@Override
	public List<AccountInfo> getTop8Attentions(Long accountid) throws BOException {
		if (accountid == null) {
			return null;
		}
		return accountDAOImpl.getTop8UserAttentions(accountid);
	}

	@Override
	public List<AccountInfo> getUserAttentionsByAccountid(Long accountid, Integer startIndex, Integer pageSize) throws BOException {
		if (accountid == null || startIndex == null || pageSize == null) {
			return null;
		}
		return accountDAOImpl.getUserAttentionsByAccountid(accountid, startIndex, pageSize);
	}

	@Override
	public Long countAllUserFans(Long accountid) throws BOException {
		if (accountid == null) {
			return 0L;
		}
		return accountDAOImpl.countAllUserFans(accountid);
	}

	@Override
	public List<AccountInfo> getUserFansByAccountid(Long accountid, Integer startIndex, Integer pageSize) throws BOException {
		if (accountid == null || startIndex == null || pageSize == null) {
			return null;
		}
		List<AccountInfo> list = accountDAOImpl.getUserFansByAccountid(accountid, startIndex, pageSize);
		if(list==null){
			return null;
		}
		for (AccountInfo accountInfo : list) {
			Long num = accountRefDAOImpl.countAcctRefs(accountid, accountInfo.getAccountid());
			if (num != null && num > 0) {
				accountInfo.setIsattention(AttentionType.yes.getCode());
			} else {
				accountInfo.setIsattention(AttentionType.no.getCode());
			}
		}
		return list;
	}

	@Override
	public void addAcctVisitor(Long visitorid, Long accountid) throws BOException {
		if (visitorid == null || accountid == null) {
			return;
		}
		Long count = acctVisitorDAOImpl.countAcctVisitor(visitorid, accountid);
		if (count != null && count > 0) {
			acctVisitorDAOImpl.updateAcctVisitor(visitorid, accountid);
		} else {
			acctVisitorDAOImpl.insertAcctVisitor(visitorid, accountid);
		}
	}

	@Override
	public Long countAllUserVisitors(Long accountid) throws BOException {
		if (accountid == null) {
			return 0L;
		}
		return acctVisitorDAOImpl.countAcctVisitor(null, accountid);
	}

	@Override
	public List<AccountInfo> getAllUserVisitors(Long accountid, Integer startIndex, Integer pageSize) throws BOException {
		if (accountid == null || startIndex == null || pageSize == null) {
			return null;
		}
		List<AccountInfo> list = accountDAOImpl.getUserVisitorsByAccountid(accountid, startIndex, pageSize);
		if(list==null){
			return null;
		}
		for (AccountInfo accountInfo : list) {
			Long num = accountRefDAOImpl.countAcctRefs(accountid, accountInfo.getAccountid());
			if (num != null && num > 0) {
				accountInfo.setIsattention(AttentionType.yes.getCode());
			} else {
				accountInfo.setIsattention(AttentionType.no.getCode());
			}
		}
		return list;
	}

	@Override
	public List<AccountInfo> getTop16UserVisitors(Long accountid) throws BOException {
		if (accountid == null) {
			return null;
		}
		return accountDAOImpl.getUserVisitorsByAccountid(accountid, 0, 16);
	}

	@Override
	public List<AccountInfo> getTop16SubjectVisitors(Long subjectid) throws BOException {
		if (subjectid == null) {
			return null;
		}
		return accountDAOImpl.getTop16SubjectVisitors(subjectid);
	}

	@Override
	public List<AccountInfo> getPagedAccountByFaq(int pagesize)
			throws BOException {
		return accountDAOImpl.getPagedAccountByFaq(pagesize);
	}

	@Override
	public List<AccountInfo> getPagedAccountByFaqRef(Long questionid,
			Integer startIndex, Integer pageSize) throws BOException {
		if (questionid == null || startIndex == null || pageSize == null) {
			return null;
		}
		List<AccountInfo> list = accountDAOImpl.getPagedAccountByFaqRef(questionid, startIndex, pageSize);
		if(list==null){
			return null;
		}
		LoginUser loginUser = ThreadObjManager.getLoginUser();
		for (AccountInfo accountInfo : list) {
			Long num = accountRefDAOImpl.countAcctRefs(loginUser.getAccountid(), accountInfo.getAccountid());
			if (num != null && num > 0) {
				accountInfo.setIsattention(AttentionType.yes.getCode());
			} else {
				accountInfo.setIsattention(AttentionType.no.getCode());
			}
		}
		return list;
	}

	@Override
	public List<AccountInfo> getPagedAccountByAnswerRef(Long answerid, Integer type, Integer startIndex, Integer pageSize) throws BOException {
		if (answerid == null || type==null || startIndex == null || pageSize == null) {
			return null;
		}
		return accountDAOImpl.getPagedAccountByAnswerRef(answerid, type, startIndex, pageSize);
	}

}
